- 本站的镜像网站: GitHub Pages, 个人网站
- 本人的 CSDN 博客: 点这里起飞
1. 概述
- 事件机制比信号槽更底层. 在事件中会默认的发送相应信号, 所以一般使用, 只需操作信号槽即可.
- 当我们需要自定义组件或修改现有组件的行为时, 就需要从事件的层面着手了.
2. 区别
- 信号槽: 其针对的是对象与对象之间的连接. 当信号发射后, 与其相连的槽函数总是会被执行的.
- 事件: 可以经过消息队列传输, 也可直接传输. 在传输过程中, 可经过事件过滤器和事件处理函数等手段来干预其.
3. 联系
- 跨线程的信号槽机制是通过事件机制完成的.
查看相关 Qt 源码可了解调用过程:
- 以下情况的信号槽连接会通过
poseEvent()
实现:- 信号槽为 `Qt::AutoConnection` 连接模式下 - 发送信号线程非当前线程时 或 信号与槽不在同一线程 - 信号槽为 `Qt::QueuedConnection` 连接模式下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// (自动连接模式 && (信号线程非本线程 || 信号与槽非同一线程) || 对列连接模式)
if ((c->connectionType == Qt::AutoConnection
&& (currentThreadData != sender->d_func()->threadData
|| receiver->d_func()->threadData != sender->d_func()->threadData))
|| (c->connectionType == Qt::QueuedConnection))
{
queued_activate(sender, signal, *c, argv);
continue;
}
// 阻塞对列模式
else if (c->connectionType == Qt::BlockingQueuedConnection)
{
blocking_activate(sender, signal, *c, argv);
continue;
}
// 其中 queued_activate 会调用 :
QCoreApplication::postEvent(c.receiver, new QMetaCallEvent(c.method, sender, signal, nargs, types, args, semaphore));- 以下情况的信号槽连接会通过
— 道理越辩越明, 欢迎留言讨论. —